package puzzle.masyu2.solver;

import puzzle.common.data.HatanException;
import puzzle.common.point.Direction;
import puzzle.masyu2.data.DangoType;
import puzzle.masyu2.data.MasyuBoard;

class DangoInitialLocationRule extends MasyuCellRule {

	@Override
	public boolean apply(MasyuBoard b, int x, int y) throws HatanException {
		boolean isChanged = false;
		switch (b.getDangoType(x, y)) {
		case SHIRO:
			isChanged |= applyShiroRule(b, x, y);
			break;
		case KURO:
			isChanged |= applyKuroRule(b, x, y);
		}
		return isChanged;
	}

	private boolean applyKuroRule(MasyuBoard b, int x, int y) throws HatanException {
		boolean isChanged = false;
		if (x < b.width - 1) {
			isChanged |= applyKuroRuleForDirection(b, x, y, Direction.E);
		}
		if (y < b.height - 1) {
			isChanged |= applyKuroRuleForDirection(b, x, y, Direction.S);
		}
		return isChanged;
	}

	private boolean applyShiroRule(MasyuBoard b, int x, int y) throws HatanException {
		boolean isChanged = false;
		if (x > 0 && x < b.width - 1) {
			isChanged |= applyShiroRuleForDirection(b, x, y, Direction.E);
		}
		if (y > 0 && y < b.height - 1) {
			isChanged |= applyShiroRuleForDirection(b, x, y, Direction.S);
		}
		return isChanged;
	}

	private boolean applyKuroRuleForDirection(MasyuBoard b, int x, int y, Direction d)
			throws HatanException {
		boolean isChanged = false;
		if (b.getDangoType(x + d.v.dx, y + d.v.dy) == DangoType.KURO) {
			isChanged |= b.setForbiddenFlag(x, y, d);
		}
		return isChanged;
	}

	private boolean applyShiroRuleForDirection(MasyuBoard b, int x, int y, Direction d)
			throws HatanException {
		boolean isChanged = false;
		if (b.getDangoType(x + d.v.dx, y + d.v.dy) == DangoType.SHIRO
				&& b.getDangoType(x - d.v.dx, y - d.v.dy) == DangoType.SHIRO) {
			isChanged |= b.setForbiddenFlag(x, y, d);
			isChanged |= b.setForbiddenFlag(x, y, d.inv());
		}
		return isChanged;
	}

}
